/**
* 版权所有：福建邮科电信业务部厦门研发中心 
*====================================================
* 文件名称: BaseJdbcDaoImpl.java
* 修订记录：
* No    日期				作者(操作:具体内容)
* 1.    2013-3-13			詹保山(创建:创建文件)
*====================================================
* 类描述：(说明未实现或其它不应生成javadoc的内容)
* JDBC操作模板
*/
package com.devframe.sysbase.dao.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.dialect.Dialect;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.devframe.sys.util.page.PageInfo;
import com.devframe.sysbase.dao.AbstractDao;
import com.devframe.sysbase.dao.BaseJdbcDao;

public class BaseJdbcDaoImpl extends AbstractDao implements BaseJdbcDao {

	protected static Logger logger = Logger.getLogger(BaseJdbcDaoImpl.class);
	/**
	 * 使用数据库方言
	 */
	private String dialect;
	
	private Dialect dialectInstance;
	
	private  NamedParameterJdbcTemplate namedParameterJdbcTemplate;
	

	
	

	public void setNamedParameterJdbcTemplate(
			NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
		this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
	}


	public  List<Map<String,Object>> sqlQueryForList(String sql, Map<String, Object> paramMap) {
		sql = sqlParse(new StringBuffer(sql), paramMap);
		return this.namedParameterJdbcTemplate.queryForList(sql, paramMap);
	}
	

	public <T> List<T> sqlQueryForList(String sql, RowMapper<T> rowMapper){
		return sqlQueryForList(sql, null,rowMapper);
	}
	public <T> List<T> sqlQueryForList(String sql, Map<String, ?> paramMap,RowMapper<T> rowMapper) {
		sql = sqlParse(new StringBuffer(sql), paramMap);
		return this.namedParameterJdbcTemplate.query(sql, paramMap, rowMapper);
	}
	
	public <T> List<T> sqlQueryForList(String sql, Map<String, ?> paramMap,Class<T> clazz) {
		sql = sqlParse(new StringBuffer(sql), paramMap);
		return this.sqlQueryForList(sql, paramMap, new BeanPropertyRowMapper<T>(clazz));
	}
	
    /**
     * 单记录查询,返回字段名为主键的MAP
     * 
     * @param queryStr
     *            查询sql
     * @return Map
     */
    public Map sqlQueryForMap(String queryStr) {
        return sqlQueryForMap(queryStr, null);
    }
    /**
     * 单记录查询,返回字段名为主键的MAP
     * 
     * @param queryStr
     *            查询sql
     * @param params
     *            查询参数
     * @return Map
     * 
     */
    public  Map  <String,Object> sqlQueryForMap(String sql, Map <String,Object> paramMap) {
    	sql = sqlParse(new StringBuffer(sql), paramMap);
    	return  this.namedParameterJdbcTemplate.queryForMap(sql, paramMap);
    }
    /**
     * 单值查询
     * 
     * @param queryStr
     *            查询sql
     * @return 字符串
     */
    public String sqlQueryForValue(String queryStr) {
        return sqlQueryForValue(queryStr, null);
    }

    /**
     * 单值查询
     * 
     * @param queryStr
     *            查询sql
     * @param params
     *            查询参数
     * @return 字符串
     * 
     */
    public String sqlQueryForValue(String queryStr, Map params) {
    	Map map = sqlQueryForMap(queryStr, params);
        if (map != null && map.values().size() > 0) {
            Object value = map.values().iterator().next();
            if (value != null) {
                return value.toString();
            }
        }
        return null;
    }
    public  PageInfo sqlQueryForPage(String sql, PageInfo pageInfo){
    	 PageInfo page = pageInfo;
	        if (page == null) {
	            page = new PageInfo();
	        }
	        return sqlQueryForPage(sql, null, page.getTotalCount(), page.getPageSize(), page.getPageIndex(), page.getSortField(), page.getSortDirect(),null);
 }
    /**
     * @param sql
     *            查询sql
     * @param pageInfo
     *            分页条件
     * @return 查询结果对象分页列表
     * 
     */
	public <T> PageInfo sqlQueryForPage(String sql, PageInfo pageInfo,RowMapper<T> rowMapper) {
	        PageInfo page = pageInfo;
	        if (page == null) {
	            page = new PageInfo();
	        }
	        return sqlQueryForPage(sql, new HashMap(), pageInfo,rowMapper);
	    }
	public <T> PageInfo sqlQueryForPage(String sql, PageInfo pageInfo,Class<T> clazz) {
        return sqlQueryForPage(sql,pageInfo,new BeanPropertyRowMapper<T>(clazz));
    }
    public <T> PageInfo sqlQueryForPage(String sql, Map<String, ?> params, PageInfo pageInfo){
		 PageInfo page = pageInfo;
	        if (page == null) {
	            page = new PageInfo();
	        }
	        return sqlQueryForPage(sql, params, page.getTotalCount(), page.getPageSize(), page.getPageIndex(), page
	            .getSortField(), page.getSortDirect(),null);
	 }
    
	 public <T> PageInfo sqlQueryForPage(String sql, Map<String, ?> params, PageInfo pageInfo,RowMapper<T> rowMapper){
		 PageInfo page = pageInfo;
	        if (page == null) {
	            page = new PageInfo();
	        }
	        return sqlQueryForPage(sql, params, page.getTotalCount(), page.getPageSize(), page.getPageIndex(), page
	            .getSortField(), page.getSortDirect(),rowMapper);
	 }
	 
	 public <T> PageInfo sqlQueryForPage(String sql, Map<String, ?> params, PageInfo pageInfo,Class<T> clazz){
		 return this.sqlQueryForPage(sql,params,pageInfo,new BeanPropertyRowMapper<T>(clazz));
	 }
	
	 
	 private <T> PageInfo sqlQueryForPage(String sql, Map params, int totalCount, int pageSize, int pageIndex,
		        String sortField, String sortDirect,RowMapper<T> rowMapper) {
		        if (sortField != null && !sortField.equals("") && sql.contains("${sortField}")) {
		            String sortExpr = sortField + " " + (sortDirect == null ? "" : sortDirect);
		            //如果排序字段中含有$符号，会出错
		            sortExpr=sortExpr.replace("$", "\\$");
		            sql=sql.replaceAll("\\$\\{sortField\\}", sortExpr);
		        }
		        String sqlStr = sqlParse(new StringBuffer(sql), params);
		        PageInfo pageInfo = new PageInfo(pageSize, pageIndex, totalCount);
		        pageInfo.setSortField(sortField);
		        pageInfo.setSortDirect(sortDirect);
		        try {
		            if (totalCount == 0) {
		                String temp = sqlStr.replaceAll("ORDER BY.*", "");
		                temp = temp.replaceAll("order by.*", "");
		                String tSql = "select count(*) TOTALCOUNT from (" + temp + ") T";
		                //获取总数
		                pageInfo.setTotalCount(this.namedParameterJdbcTemplate.queryForInt(tSql, params));
		            } else {
		                pageInfo.setTotalCount(totalCount);
		            }
		            if (pageIndex == 0) {
		                pageInfo.setPageIndex(1);
		            } else {
		                pageInfo.setPageIndex(pageIndex);
		            }
		            pageInfo.setPageSize(pageSize);

		            if (pageInfo.getPageSize() != -1) {
			            Integer offset=(pageInfo.getPageIndex() - 1) * pageInfo.getPageSize();
			            Integer limit= pageInfo.getPageIndex()  * pageInfo.getPageSize();
			            sqlStr=dialectInstance.getLimitString(sqlStr, offset+1, limit);
			            sqlStr=sqlStr.replaceFirst("\\?", " :limit").replaceFirst("\\?", " :offset");
			            if(params==null){
			            	params=new HashMap<String,Object>();
			            }
			            params.put("offset", offset);
			            params.put("limit", limit);
		            }
		            
		            List dataList=null;
		            if(rowMapper!=null){
		            	dataList= this.namedParameterJdbcTemplate.query(sqlStr, params, rowMapper);
		            }else{
		            	dataList=this.namedParameterJdbcTemplate.queryForList(sqlStr, params);
		            }
		            pageInfo.setDataList(dataList);
		            if (pageInfo.getPageSize() == -1) {
		                pageInfo.setPageCount(1);
		                pageInfo.setPageIndex(1);
		                pageInfo.setTotalCount(pageInfo.getDataList().size());
		            }
		        } catch (Exception e) {
		            logger.error(sql);
		            e.printStackTrace();
		        }
		        return pageInfo;
		    }
//	    /**
//	     * 执行JDBC SQL更新语句,也可以执行不需要返回值的过程
//	     * 
//	     * @param sql
//	     *            sql
//	     * @return 更新影响的记录数
//	     */
//	 public int executeSqlUpdate(String sql) {
//	        return executeSqlUpdate(sql, null);
//	    }
//	 
//	    /**
//	     * 执行JDBC SQL更新语句,也可以执行不需要返回值的过程
//	     * 
//	     * @param sql
//	     *            sql
//	     * @param params
//	     *            参数，可以为null
//	     * @return 更新影响的记录数
//	     */
//	 public int executeSqlUpdate(String sql, Map params){
//		return this.namedParameterJdbcTemplate.execute(sql, params, null);
//	 }
//	 
//	 
	 /**
	  * 执行JDBC SQL更新语句,带有回调动作
	  * @param sql
	  * @param params
	  * @param action
	  * @return
	  * @author:詹保山
	  */
	 public <T> T executeSqlUpdate(String sql, Map<String, ?> params,PreparedStatementCallback<T> action){
		 return this.namedParameterJdbcTemplate.execute(sql, params, action);
	 }




	public String getDialect() {
		return dialect;
	}



	public void setDialect(String dialect) {
		this.dialect = dialect;
	    try {
			dialectInstance=(Dialect)Class.forName(dialect).newInstance();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("设置Spring JDBC的方言错误,无法实例化："+this.dialect);
		} 
	}




	
	
	
}
